package com.example.questionnaires.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.questionnaires.common.PageResult;
import com.example.questionnaires.common.Result;
import com.example.questionnaires.dto.UserDTO;
import com.example.questionnaires.entity.User;
import com.example.questionnaires.vo.UserVO;
import com.example.questionnaires.form.LoginForm;
import com.example.questionnaires.form.RegisterForm;
import com.example.questionnaires.mapper.UserMapper;
import com.example.questionnaires.service.UserService;
import com.example.questionnaires.util.UserHolder;
import com.example.questionnaires.util.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import cn.hutool.core.util.StrUtil;

import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public Result<UserDTO> login(LoginForm loginForm) {
        // 1. 校验参数
        if (StrUtil.isBlank(loginForm.getUsername()) || StrUtil.isBlank(loginForm.getPassword())) {
            return Result.error("用户名或密码不能为空");
        }

        // 2. 查询用户
        User user = getOne(new LambdaQueryWrapper<User>()
            .eq(User::getUsername, loginForm.getUsername()));
        if (user == null) {
            return Result.error("用户不存在");
        }

        // 3. 校验密码
        String encryptedPassword = DigestUtils.md5DigestAsHex(loginForm.getPassword().getBytes());
        if (!encryptedPassword.equals(user.getPassword())) {
            return Result.error("密码错误");
        }

        // 4. 校验状态
        if (user.getStatus() == 0) {
            return Result.error("账号已被禁用");
        }

        // 5. 生成token
        String token = JwtUtil.generateToken(user.getUsername());

        // 6. 转换为DTO
        UserDTO userDTO = new UserDTO();
        BeanUtils.copyProperties(user, userDTO);
        userDTO.setToken(token);

        return Result.success(userDTO);
    }

    @Override
    public Result<Void> register(RegisterForm registerForm) {
        // 1. 校验参数
        if (StrUtil.isBlank(registerForm.getUsername()) || 
            StrUtil.isBlank(registerForm.getPassword()) ||
            StrUtil.isBlank(registerForm.getConfirmPassword())) {
            return Result.error("必填项不能为空");
        }

        // 2. 校验两次密码是否一致
        if (!registerForm.getPassword().equals(registerForm.getConfirmPassword())) {
            return Result.error("两次密码不一致");
        }

        // 3. 校验用户名是否已存在
        long count = count(new LambdaQueryWrapper<User>()
            .eq(User::getUsername, registerForm.getUsername()));
        if (count > 0) {
            return Result.error("用户名已存在");
        }

        // 4. 创建用户
        User user = new User();
        user.setUsername(registerForm.getUsername());
        // 密码加密
        String encryptedPassword = DigestUtils.md5DigestAsHex(registerForm.getPassword().getBytes());
        user.setPassword(encryptedPassword);
        user.setRole(2); // 默认普通用户
        user.setStatus(1); // 默认启用
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());

        save(user);

        return Result.success();
    }

    @Override
    public void updatePassword(Long userId, String oldPassword, String newPassword) {
        // 1. 查询用户
        User user = getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 2. 校验旧密码
        String oldMd5 = DigestUtils.md5DigestAsHex(oldPassword.getBytes());
        if (!oldMd5.equals(user.getPassword())) {
            throw new RuntimeException("原密码错误");
        }

        // 3. 更新密码
        user.setPassword(DigestUtils.md5DigestAsHex(newPassword.getBytes()));
        updateById(user);
    }

    @Override
    public User getUserById(Long id) {
        return getById(id);
    }

    @Override
    public void updateUser(User user) {
        if (!updateById(user)) {
            throw new RuntimeException("更新失败");
        }
    }

    @Override
    public void deleteUser(Long id) {
        if (!removeById(id)) {
            throw new RuntimeException("删除失败");
        }
    }

    @Override
    public void banUser(Long id) {
        User user = getById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        user.setStatus(0);
        if (!updateById(user)) {
            throw new RuntimeException("禁用失败");
        }
    }

    @Override
    public void unbanUser(Long id) {
        User user = getById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        user.setStatus(1);
        if (!updateById(user)) {
            throw new RuntimeException("启用失败");
        }
    }

    @Override
    public Result<PageResult<User>> list(Integer page, Integer size) {
        // 分页查询
        Page<User> pageParam = new Page<>(page, size);
        Page<User> pageResult = page(pageParam);
        return Result.success(new PageResult<>(pageResult));
    }

    @Override
    public Result<Void> add(UserDTO userDTO) {
        // 1. 校验用户名是否已存在
        Long count = query()
                .eq("username", userDTO.getUsername())
                .count();
        if (count > 0) {
            return Result.error("用户名已存在");
        }

        // 2. 创建用户对象
        User user = new User();
        BeanUtils.copyProperties(userDTO, user);
        user.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes())); // 默认密码
        user.setStatus(1);  // 默认启用
        user.setRole(2);  // 默认普通用户

        // 3. 保存用户
        save(user);
        
        return Result.success();
    }

    @Override
    public boolean updateById(User user) {
        return userMapper.updateById(user) > 0;
    }

    @Override
    public Result<Void> deleteById(Long id) {
        // 1. 校验用户是否存在
        User user = getById(id);
        if (user == null) {
            return Result.error("用户不存在");
        }

        // 2. 删除用户
        removeById(id);
        
        return Result.success();
    }

    @Override
    public Result<Void> resetPassword(Long id) {
        // 1. 校验用户是否存在
        User user = getById(id);
        if (user == null) {
            return Result.error("用户不存在");
        }

        // 2. 重置密码为123456
        String defaultPassword = DigestUtils.md5DigestAsHex("123456".getBytes());
        user.setPassword(defaultPassword);
        updateById(user);
        
        return Result.success();
    }

    @Override
    public Result<Void> updateStatus(Long id, Integer status) {
        // 1. 校验用户是否存在
        User user = getById(id);
        if (user == null) {
            return Result.error("用户不存在");
        }

        // 2. 更新状态
        user.setStatus(status);
        updateById(user);
        
        return Result.success();
    }

    @Override
    public List<User> getAllUsers() {
        return list();
    }

    @Override
    public User getUserFromToken(String token) {
        try {
            // 1. 校验token
            if (!JwtUtil.validateToken(token)) {
                return null;
            }
            
            // 2. 解析token获取用户名
            String username = JwtUtil.getUsernameFromToken(token);
            if (StrUtil.isBlank(username)) {
                return null;
            }
            
            // 3. 查询用户
            User user = getOne(new LambdaQueryWrapper<User>()
                .eq(User::getUsername, username)
                .eq(User::getStatus, 1));
                
            return user;
        } catch (Exception e) {
            log.error("解析token失败", e);
            return null;
        }
    }

    private UserVO convertToVO(User user) {
        if (user == null) {
            return null;
        }
        UserVO vo = new UserVO();
        vo.setId(user.getId());
        vo.setUsername(user.getUsername());
        vo.setEmail(user.getEmail());
        vo.setPhone(user.getPhone());
        vo.setRole(user.getRole());
        vo.setStatus(user.getStatus());
        vo.setCreateTime(user.getCreateTime());
        return vo;
    }
} 